<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Nools Example</title>
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/nools@0.4.4/nools.min.js"></script> -->
    <script src="nools.js"></script>
</head>
<style>
.flex{
   display: flex;
   justify-content: center;
}
.flex-item {
    padding: 40px 60px;
    background-color: #ccf4c1;
}
.flex-item:nth-child(odd){
   background-color:blanchedalmond;
}
</style>
<body>
    <div class="flex">
        <div id="rule" class="flex-item"></div>
        <div id="data" class="flex-item"></div>
        <div id="result" class="flex-item"></div>
    </div>
    <script>
        // 定义规则
        const rule = `
            // define Person {
            //     name: String,
            //     age: Number,
            //     ageTypes: Array,
            // }
            define Person {
                constructor: function(options){
                    this.name = options.name;
                    this.age = options.age;
                    this.ageTypes = options.ageTypes;
                },
                toString : function(){
                    return ["Person : [", [this.name, this.age, this.ageTypes].join(":"), "]"].join("");
                }
            }
            rule '添加类型' {
                when {
                    p: Person isUndefinedOrNull(p.ageTypes);
                }
                then {
                    p.ageTypes = [];
                }
            }
            rule '老年' {
                when {
                    p: Person p.age >= 60;
                }
                then {
                    p.ageTypes?.push('老年人');
                    sayHello(p);
                }
            }
            rule '中年' {
                when {
                    p: Person p.age >= 35 && p.age < 60;
                }
                then {
                    p.ageTypes?.push('中年人');
                    sayHello(p);
                }
            }
            rule '青年' {
                when {
                    p: Person p.age >= 25 && p.age < 35;
                }
                then {
                    p.ageTypes?.push('青年人');
                    sayHello(p);
                }
            }
            rule '成年' {
                when {
                    p: Person p.age >= 18;
                }
                then {
                    if (!p.ageTypes) {
                        p.ageTypes = [];
                    }
                    p.ageTypes?.push('成年人');
                    sayHello(p);
                }
            }
            rule '少年' {
                when {
                    p: Person p.age >= 12 && p.age < 18;
                }
                then {
                    p.ageTypes?.push('少年');
                    sayHello(p);
                }
            }
            rule '儿童' {
                when {
                    p: Person p.age >= 3 && p.age < 12;
                }
                then {
                    p.ageTypes?.push('儿童');
                    sayHello(p);
                }
            }
            rule '婴儿' {
                when {
                    p: Person p.age < 3;
                }
                then {
                    p.ageTypes?.push('婴儿');
                    sayHello(p);
                }
            }
            rule '未知年龄' {
                when {
                    p: Person isUndefinedOrNull(p.age);
                }
                then {
                    p.ageTypes?.push('未知年龄');
                    sayHello(p);
                }
            }
        `;
        const names = [];
        const showName = function() {
            console.log('two ageTypes names', names);
        }
        const sayHello = function (p) {
            console.log(`${p.name}的年龄范围：${p.ageTypes.join('&')}`);
            if (p.ageTypes.length > 1) {
                names.push(p.name);
                showName();
            }
            console.log(p.toString())
        }

        // class Person {
        //     constructor (person) {
        //         this.name = person.name;
        //         this.age = person.age;
        //         this.ageTypes = person.ageTypes;
        //     }
        // }
        // 编译规则
        const flow = nools.compile(rule, {
            // define: {
            //     Person: Person
            // },
            scope: {
                sayHello,
            },
            name: '判断年龄范围'
        });

        // 创建Person类
        const Person = flow.getDefined('Person');

        // 创建会话
        const session = flow.getSession();
        const persons = [
            { name: 'Ming', age: 45 },
            { name: 'John', age: 20 },
            { age: 8 },
            { name: 'Hong' },
            { name: 'Yellow', age: 63 }
        ];
        // 创建人物实例 & 将实例添加到会话
        persons.forEach(item => {
            const person = new Person(item);
            session.assert(_.cloneDeep(person));
        })
        session.on("fire", function (name, rule) {
            console.log('on fire', name, rule);
        });
        // 执行规则
        session.match().then(() => {
            console.log('Rules executed.');
            document.getElementById('rule').innerHTML = `规则：<br/><pre>${rule}</pre>`;
            document.getElementById('data').innerHTML = `数据：<br/><pre>${JSON.stringify(persons, null, 4)}</pre>`;
            document.getElementById('result').innerHTML = `结果：<br/><pre>${JSON.stringify(session.getFacts(), null, 4)}</pre>`;
        },
        (err) => {
            //uh oh an error occurred
            console.error(err.stack);
        });
    </script>

</body>

</html>